﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Comic.Common
{
    /// <summary>a single Setting-Control - holds information how to display and edit the associated setting</summary>
    public class cSettingControl
    {
        #region internal Constants

        /// <summary>internal minimum-height for a control</summary>
        private const int _MinimumControlHeight = 30;

        #endregion

        #region internal Fields and Objects

        /// <summary>Type of Control to use</summary>
        private eSettingControlType _ControlType;
        /// <summary>Title-Text to use</summary>
        private string _TitleText;
        /// <summary>Minimum Value if numeric</summary>
        private decimal _MinValue;
        /// <summary>Maximum Value if numeric</summary>
        private decimal _MaxValue;
        /// <summary>Number of decimal places if numeric</summary>
        private int _DecimalPlaces;
        /// <summary>Value for string-based Types</summary>
        private string _ValueString;
        /// <summary>Value for numerical Types</summary>
        private decimal _ValueNumeric;
        /// <summary>Value for boolean Types</summary>
        private bool _ValueBool;
        /// <summary>Value for date- or time-based Types</summary>
        private DateTime _ValueDateTime;
        /// <summary>List for Selection-Values</summary>
        private List<sSettingSelectionValue> _SelectionValues;
        /// <summary>the minimum height for the Control</summary>
        private int _MinimumHeight;

        #endregion
        
        #region basic Properties

        /// <summary>The Text for the Label of the Item (always required)</summary>
        public string TitleText
        {
            get { return _TitleText; }
            set { _TitleText = value; }
        }

        /// <summary>The Type of Control to use</summary>
        public eSettingControlType ControlType
        {
            get { return _ControlType; }
            set { _ControlType = value; }
        }

        #endregion

        #region Value-Fields

        /// <summary>Value for date or time fields / types</summary>
        public DateTime ValueDateTime
        {
            get { return _ValueDateTime; }
            set { _ValueDateTime = value; }
        }

        /// <summary>Value for boolean fields / types</summary>
        public bool ValueBool
        {
            get { return _ValueBool; }
            set { _ValueBool = value; }
        }

        /// <summary>Value for numeric fields / types</summary>
        public decimal ValueNumeric
        {
            get { return _ValueNumeric; }
            set { _ValueNumeric = value; }
        }

        /// <summary>Value for string fields / types</summary>
        public string ValueString
        {
            get { return _ValueString; }
            set { _ValueString = value; }
        }

        #endregion

        #region additional Properties for Numeric / Decimal Values

        /// <summary>decimal places to display (if numeric value)</summary>
        public int DecimalPlaces
        {
            get { return _DecimalPlaces; }
            set { _DecimalPlaces = value; }
        }

        /// <summary>Max-Value for Input (if numeric value)</summary>
        public decimal MaxValue
        {
            get { return _MaxValue; }
            set { _MaxValue = value; }
        }

        /// <summary>Min-Value for Input (if numeric value)</summary>
        public decimal MinValue
        {
            get { return _MinValue; }
            set { _MinValue = value; }
        }

        #endregion

        #region additional Properties for "select from list" Values

        /// <summary>List with Selection-Values (for DropDownList and Radio-Buttons)</summary>
        public List<sSettingSelectionValue> SelectionValues
        {
            get { return _SelectionValues; }
            set { _SelectionValues = value; }
        }

        #endregion

        #region additional Properties for multi-line TextBox

        /// <summary>Minimum Height for the used Control (set for MultiLine Textbox - default and min is 30)</summary>
        public int MinimumHeight
        {
            get { return _MinimumHeight; }
            set
            {
                // apply min-height - check for min-height
                this._ApplyMinHeight_(value);
            }
        }
        
        #endregion

        #region (overloaded) Constructor

        /// <summary>basic (empty) constructor</summary>
        public cSettingControl()
        {
            // call basic constructor
            this._InitClass_(eSettingControlType.Undefined, string.Empty, 0, _MinimumControlHeight, 0, 100);
        }

        /// <summary>default constructor - define type and title</summary>
        /// <param name="ControlType">the Control-Type</param>
        /// <param name="TitleText">the Title-Text for the Control</param>
        public cSettingControl(eSettingControlType ControlType, string TitleText)
        {
            // call basic constructor
            this._InitClass_(ControlType, TitleText, 0, _MinimumControlHeight, 0, 100);
        }

        /// <summary>Constructor for string-based types</summary>
        /// <param name="ControlType">the Control-Type</param>
        /// <param name="TitleText">the Title-Text for the Control</param>
        /// <param name="Value">the string Value to apply as Control-Value</param>
        public cSettingControl(eSettingControlType ControlType, string TitleText, string Value)
        {
            // call basic constructor
            this._InitClass_(ControlType, TitleText, 0, _MinimumControlHeight, 0, 100);
            // set string-value
            this._ValueString = Value;
        }

        /// <summary>Constructor for boolean types</summary>
        /// <param name="ControlType">the Control-Type</param>
        /// <param name="TitleText">the Title-Text for the Control</param>
        /// <param name="Value">the boolean Value to apply as Control-Value</param>
        public cSettingControl(eSettingControlType ControlType, string TitleText, bool Value)
        {
            // call basic constructor
            this._InitClass_(ControlType, TitleText, 0, _MinimumControlHeight, 0, 100);
            // set bool-value
            this._ValueBool = Value;
        }

        /// <summary>Constructor for numeric types</summary>
        /// <param name="ControlType">the Control-Type</param>
        /// <param name="TitleText">the Title-Text for the Control</param>
        /// <param name="Value">the numeric (decimal) Value to apply as Control-Value</param>
        public cSettingControl(eSettingControlType ControlType, string TitleText, decimal Value, int DecimalPlaces, decimal MinValue, decimal MaxValue)
        {
            // call basic constructor
            this._InitClass_(ControlType, TitleText, DecimalPlaces, _MinimumControlHeight, MinValue, MaxValue);
            // set numeric value
            this._ValueNumeric = Value;
        }

        /// <summary>Constructor for date/time types</summary>
        /// <param name="ControlType">the Control-Type</param>
        /// <param name="TitleText">the Title-Text for the Control</param>
        /// <param name="Value">the DateTime Value to apply as Control-Value</param>
        public cSettingControl(eSettingControlType ControlType, string TitleText, DateTime Value)
        {
            // call basic constructor
            this._InitClass_(ControlType, TitleText, 0, _MinimumControlHeight, 0, 100);
            // set datime-value
            this._ValueDateTime = Value;
        }

        /// <summary>Constructor for selection types</summary>
        /// <param name="ControlType">the Control-Type</param>
        /// <param name="TitleText">the Title-Text for the Control</param>
        /// <param name="Value">the string-based Value to apply as pre-selected Control-Value</param>
        /// <param name="SelectionList">List with Items that can be selected</param>
        public cSettingControl(eSettingControlType ControlType, string TitleText, string Value, List<sSettingSelectionValue> SelectionList)
        {
            // call basic constructor
            this._InitClass_(ControlType, TitleText, 0, _MinimumControlHeight, 0, 100);
            // set string-value
            this._ValueString = Value;
            // set list
            this._SelectionValues = SelectionList;
        }

        /// <summary>Constructor for string-based multiline type</summary>
        /// <param name="ControlType">the Control-Type</param>
        /// <param name="TitleText">the Title-Text for the Control</param>
        /// <param name="Value">the string Value to apply as Control-Value</param>
        /// <param name="MinHeight">the Min-Height for the Control</param>
        public cSettingControl(eSettingControlType ControlType, string TitleText, string Value, int MinHeight)
        {
            // call basic constructor
            this._InitClass_(ControlType, TitleText, 0, _MinimumControlHeight, 0, 100);
            // set string-value
            this._ValueString = Value;
            // aply min-height
            this._ApplyMinHeight_(MinHeight);
        }

        #endregion

        #region inner worker - Implementation

        /// <summary>internal Constructor-Code</summary>
        /// <param name="ControlType">Type of Cntrol</param>
        /// <param name="TitleText">Title-Text</param>
        /// <param name="DecimalPlaces">number of Decimal-Places if fumeric</param>
        /// <param name="MinimumHeight">Min-Height (not applied below min-height)</param>
        /// <param name="MinValue">Min-Value numeric</param>
        /// <param name="MaxValue">Max-Value numeric</param>
        private void _InitClass_(eSettingControlType ControlType, string TitleText, int DecimalPlaces,
            int MinimumHeight, decimal MinValue, decimal MaxValue)
        {
            // init from parameters
            this._ControlType = ControlType;
            this._TitleText = TitleText;
            this._DecimalPlaces = DecimalPlaces;
            this._MinValue = MinValue;
            this._MaxValue = MaxValue;
            // init min-height - check for min-height
            this._ApplyMinHeight_(MinimumHeight);
            // init with defaults - will be set by Overload
            this._SelectionValues = new List<sSettingSelectionValue>();
            this._ValueBool = false;
            this._ValueDateTime = DateTime.MinValue;
            this._ValueNumeric = -1;
            this._ValueString = string.Empty;
        }

        /// <summary>internal Code to apply a new Min-Height for the Control</summary>
        /// <param name="NewMinHeight">the Height to apply (if below min, gets set to min)</param>
        private void _ApplyMinHeight_(int NewMinHeight)
        {
            // init min-height - check for min-height
            if (NewMinHeight >= _MinimumControlHeight) // not below min - apply value
            {
                this._MinimumHeight = NewMinHeight;
            }
            else // below min - set min
            {
                this._MinimumHeight = _MinimumControlHeight;
            }
        }

        #endregion
    }
}